package edu.pku.sei.mdabase.infrastructure.model;

import java.util.ArrayList;
import java.util.List;

import edu.pku.sei.mdabase.basictypes.OCLInvalid;
import edu.pku.sei.mdabase.core.IDataType;
import edu.pku.sei.mdabase.core.MDAConstant;
import edu.pku.sei.mdabase.infrastructure.collection.OclCollection;
import edu.pku.sei.mdabase.infrastructure.graph.Graph;
import edu.pku.sei.mdabase.infrastructure.graph.GraphEdge;
import edu.pku.sei.mdabase.infrastructure.metamodel.MetaAttribute;
import edu.pku.sei.mdabase.infrastructure.metamodel.MetaReference;

public class MReference extends GraphEdge<MClass,MModelGraph> implements MModelObject {

	private IDataType type;
	private List<MAttribute> attributes;

	public IDataType getType() {
		return type;
	}

	public void setType(IDataType type) {
		this.type = type;
		
/*		
		if(((MetaReference) type).getOpposite()!=null&&((MetaReference) type).getOpposite().isComposite()){
			this.type=((MetaReference) type).getOpposite();
			
			isReversed=true;
			
			MClass tmp = super.getSource();
			super.setSource(super.getTarget());
			super.setTarget(tmp);
			
			System.out.println("switch the source and target in MReference.java");
				}
*/
	}
	
	public MClass getOwner(){
		return getSource();
	}
	
	public MClass getReferencedClass(){
		return getTarget();
	}

	public MAttribute getAttribute(String name) {
		List<MAttribute> l = getAttributes();
		for(MAttribute a : l) {
			if(name.equals(a.getName()))
				return a;
		}
		MetaReference type = (MetaReference) getType();
		if(type!=null){
			MetaAttribute ra = type.getAttribute(name);
			
			if(ra!=null){
				MAttribute att =this.getHost(Graph.BASE).createAttribute(null,ra);
				att.setName(name);
				att.setType(ra.getType());
				att.setValue(ra.getDefaultValue());
				
				l.add(att);
				att.setHost(this);
				
				return att;
			}
		}
		
		return null;
	}

	public List<MAttribute> getAttributes() {
		if(this.attributes==null)
			this.attributes = new ArrayList<MAttribute>();
		return this.attributes;
		//return null;
	}

	public MClass getEnd(MClass mClass, String name) {
		if(this.getSource()==mClass){
			if(name.equals(getType().getName()))
				return this.getTarget();
		}
		else if(this.getTarget()==mClass){
			if(((MetaReference) getType()).getOpposite()!=null&&name.equals(((MetaReference) getType()).getOpposite().getName()))
				return  this.getSource();
		}
		return null;
	}

	@Override
	public Object get(String name) {
		return get(name,Graph.BASE);
	}

	@Override
	public Object get(String name, Object key) {
		MAttribute att = getAttribute(name);
		if (att == null) {
			return MDAConstant.UNINITIATED_VALUE;
		} else
			return att;
	}

	@Override
	public boolean set(String name, Object value) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean set(String name, Object value, Object key) {
		// TODO Auto-generated method stub
		return false;
	}	
}
